import axios from 'axios';
import YTDlpWrap from 'yt-dlp-wrap';
import ffmpeg from 'fluent-ffmpeg';

export class MediaService {
  private ytDlp: YTDlpWrap;

  constructor() {
    this.ytDlp = new YTDlpWrap();
  }

  async parseUrl(url: string) {
    try {
      // 检测URL类型
      const urlType = this.detectUrlType(url);
      
      switch (urlType) {
        case 'youtube':
        case 'bilibili':
        case 'other':
          return await this.parseWithYtDlp(url);
        case 'm3u8':
          return await this.parseM3U8(url);
        case 'mp4':
        case 'webm':
          return await this.parseDirectVideo(url);
        default:
          return await this.parseGeneric(url);
      }
    } catch (error) {
      throw new Error(`Failed to parse URL: ${(error as Error).message}`);
    }
  }

  async getMediaInfo(url: string) {
    try {
      const info = await this.ytDlp.getVideoInfo(url);
      return {
        title: info.title,
        duration: info.duration,
        thumbnail: info.thumbnail,
        formats: info.formats,
        uploader: info.uploader,
        description: info.description
      };
    } catch (error) {
      throw new Error(`Failed to get media info: ${(error as Error).message}`);
    }
  }

  async getAvailableQualities(url: string) {
    try {
      const info = await this.ytDlp.getVideoInfo(url);
      const qualities = info.formats
        .filter((f: any) => f.vcodec !== 'none')
        .map((f: any) => ({
          quality: f.height || 'audio',
          format: f.format,
          url: f.url,
          filesize: f.filesize
        }))
        .sort((a: any, b: any) => (b.quality || 0) - (a.quality || 0));

      return qualities;
    } catch (error) {
      throw new Error(`Failed to get qualities: ${(error as Error).message}`);
    }
  }

  private detectUrlType(url: string): string {
    if (url.includes('youtube.com') || url.includes('youtu.be')) {
      return 'youtube';
    }
    if (url.includes('bilibili.com')) {
      return 'bilibili';
    }
    if (url.endsWith('.m3u8')) {
      return 'm3u8';
    }
    if (url.endsWith('.mp4')) {
      return 'mp4';
    }
    if (url.endsWith('.webm')) {
      return 'webm';
    }
    return 'other';
  }

  private async parseWithYtDlp(url: string) {
    const info = await this.ytDlp.getVideoInfo(url);
    return {
      type: 'video',
      title: info.title,
      url: url,
      formats: info.formats,
      thumbnail: info.thumbnail,
      duration: info.duration
    };
  }

  private async parseM3U8(url: string) {
    const response = await axios.get(url);
    return {
      type: 'm3u8',
      url: url,
      content: response.data
    };
  }

  private async parseDirectVideo(url: string) {
    const response = await axios.head(url);
    return {
      type: 'direct',
      url: url,
      contentType: response.headers['content-type'],
      contentLength: response.headers['content-length']
    };
  }

  private async parseGeneric(url: string) {
    try {
      const response = await axios.get(url);
      return {
        type: 'generic',
        url: url,
        contentType: response.headers['content-type']
      };
    } catch (error) {
      throw new Error(`Failed to parse generic URL: ${(error as Error).message}`);
    }
  }
}
